package net.zoneland.geological.usermanage.service;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.zoneland.geological.project.dao.Tbl_projectDao;
import net.zoneland.geological.project.dao.Tbl_zhtDao;
import net.zoneland.geological.project.entity.Tbl_project;
import net.zoneland.geological.project.entity.Tbl_zht;
import net.zoneland.geological.station.dao.Tbl_station_infoDao;
import net.zoneland.geological.station.entity.Tbl_station_info;
import net.zoneland.geological.system.dao.Tbl_areaDao;
import net.zoneland.geological.system.entity.Tbl_area;
import net.zoneland.geological.usermanage.dao.Tbl_roleDao;
import net.zoneland.geological.usermanage.dao.Tbl_userDao;
import net.zoneland.geological.usermanage.dao.Tbl_user_datapermissionDao;
import net.zoneland.geological.usermanage.dao.Tbl_user_roleDao;
import net.zoneland.geological.usermanage.entity.Tbl_user;
import net.zoneland.geological.usermanage.entity.Tbl_user_datapermission;

/**
 * tbl_user_datapermission[用户数据权限配置表]表操作Serfice实现类

 * 表   名：TBL_USER_DATAPERMISSIONSERVICEIMPL<br/>
 * 注   释：用户数据权限配置表<br/>
 * 作   者：李义<br/>
 * 日   期：2017-08-09 18:46:00
**/
@Service("tbl_user_datapermissionService")
public class Tbl_user_datapermissionServiceImpl implements Tbl_user_datapermissionServiceI { 

	public static Logger logger = Logger.getLogger(Tbl_user_datapermissionServiceImpl.class);

	/**
	 * 自动注入DAO对象
	**/
	@Autowired
	private Tbl_user_datapermissionDao tbl_user_datapermissionDao;
	
	@Autowired
	private Tbl_projectDao tbl_projectDao;

	@Autowired
	private Tbl_zhtDao tbl_zhtDao;
	
	@Autowired
	private Tbl_areaDao tbl_areaDao;
	
	@Autowired
	private Tbl_userDao tbl_userDao;
	
	@Autowired
	private Tbl_roleDao tbl_roleDao;
	
	@Autowired
	private Tbl_station_infoDao tbl_station_infoDao;
	
	@Autowired
	private Tbl_user_roleDao tbl_user_roleDao;
	/**
	 * 新增或者更新数据方法接口
	**/
	@Override
	public Tbl_user_datapermission addOrUpdate( Tbl_user_datapermission tbl_user_datapermission )  throws Exception{
		if ( tbl_user_datapermission == null ) {
			logger.error(Tbl_user_datapermission.class.getName() + "对象参数信息为NULL，addOrUpdate方法无法继续！");
			return tbl_user_datapermission;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put( "object_code", tbl_user_datapermission.getObject_code() );
		map.put( "object_type", tbl_user_datapermission.getObject_type() );
		map.put( "perm_code", tbl_user_datapermission.getPerm_code() );
		map.put( "perm_level", tbl_user_datapermission.getPerm_level() );
		List<Tbl_user_datapermission> list  = tbl_user_datapermissionDao.getList(map);
		if( list != null && !list.isEmpty() ){
			tbl_user_datapermissionDao.edit( tbl_user_datapermission );
			return tbl_user_datapermission;
		}else{
			if( tbl_user_datapermission.getId() ==null || tbl_user_datapermission.getId().trim().isEmpty() ){
				tbl_user_datapermission.setId( UUID.randomUUID() + "" );
		    }
			tbl_user_datapermissionDao.add( tbl_user_datapermission );
			return tbl_user_datapermission;
		}
	}
	/**
	 * 新增数据方法实现
	**/
	@Override
	public boolean add(Tbl_user_datapermission tbl_user_datapermission) throws Exception{
		tbl_user_datapermissionDao.add( tbl_user_datapermission );
		return true;
	}
	/**
	 * 更新数据方法实现
	**/
	@Override
	public boolean update(Tbl_user_datapermission tbl_user_datapermission) throws Exception{
		tbl_user_datapermissionDao.edit( tbl_user_datapermission );
		return true;
	}
	/**
	 * 查询数据方法实现
	**/
	@Override
	public Tbl_user_datapermission get( Map<String, Object> map ) throws Exception{
		return tbl_user_datapermissionDao.get( map );
	}
	/**
	 * 查询数据方法实现（列表）
	**/
	@Override
	public List<Tbl_user_datapermission> getList(Map<String, Object> map) throws Exception{ 
		return tbl_user_datapermissionDao.getList( map );
	}
	
	/**
	 * 查询数据总数方法实现
	**/
	@Override
	public int getListCount(Map<String, Object> map) throws Exception{ 
		return tbl_user_datapermissionDao.getListCount( map );
	}
	
	/**
	 * 数据删除方法实现
	**/
	@Override
	public boolean delete(Map<String, Object> map) throws Exception{ 
		tbl_user_datapermissionDao.delete( map );
		return true;
	}
	
	/**
	 * 根据用户获取用户可以访问到的所有灾害体ID列表
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<String> getZhtIdsWithPermission( String login_name ) throws Exception {
		Map<String, Object> paramMap = new HashMap<>();
		List<Tbl_user_datapermission> user_datapermission_list = null;
		List<Tbl_zht> zhts = null;
		List<String> zhtIds = new ArrayList<>();
		List<String> projectIds = null;
		
		user_datapermission_list = listAllDatapermission( login_name );
		
		//将所有的权限信息换算为灾害体信息列表
		if( user_datapermission_list != null && !user_datapermission_list.isEmpty() ) {
			for( Tbl_user_datapermission perm : user_datapermission_list ) {
				if( "ZHT".equals( perm.getPerm_level() )) {
					if( !zhtIds.contains( perm.getPerm_code() )) {
						zhtIds.add( perm.getPerm_code() );
					}
				}
			}
			//获取用户能查询到的所有项目ID
			projectIds = getProjectIdsWithPermission( user_datapermission_list );
			if( projectIds != null && !projectIds.isEmpty() ) {
				for( String projectId : projectIds ) {
					paramMap.clear();
					paramMap.put( "project_id", projectId );
					zhts = tbl_zhtDao.getList(paramMap);
					if( zhts != null && !zhts.isEmpty() ) {
						for( Tbl_zht zht : zhts ) {
							if( !zhtIds.contains( zht.getId() )) {
								zhtIds.add( zht.getId() );
							}
						}
					}
				}
			}
		}
		return zhtIds;
	}
	
	/**
	 * 根据用户登录名，获取用户所有的数据权限配置
	 * @param login_name
	 * @return
	 */
	private List<Tbl_user_datapermission> listAllDatapermission( String login_name ) {
		Map<String, Object> paramMap = new HashMap<>();
		List<Tbl_user_datapermission> user_datapermission_list = null;
		List<Tbl_user_datapermission> user_datapermission_list_temp = null;
		Tbl_user user = null;
		List<String> roleIds = null;
		List<String> roleCodes = null;
		
		paramMap.put( "login_name" , login_name );
		user = tbl_userDao.get( paramMap );
		
		if( user != null ) {
			//查询该用户所属的所有角色
			paramMap.clear();
			paramMap.put( "user_id", user.getId() );
			roleIds = tbl_user_roleDao.listRoleIdsWithFilter( paramMap );
		}
		
		if( roleIds != null && !roleIds.isEmpty() ) {
			paramMap.clear();
			paramMap.put( "ids", roleIds );
			roleCodes = tbl_roleDao.listRoleCodeWithFilter( paramMap );
		}
		
		if( roleCodes != null && !roleCodes.isEmpty() ) {
			paramMap.clear();
			paramMap.put( "object_type", "ROLE" );
			paramMap.put( "object_codes", roleCodes );
			user_datapermission_list = tbl_user_datapermissionDao.getList( paramMap );
		}
		if( user_datapermission_list == null ) {
			user_datapermission_list = new ArrayList<>();
		}
		
		//再查询用户的所有数据权限信息
		paramMap.clear();
		paramMap.put( "object_type", "USER" );
		paramMap.put( "object_code", login_name );
		user_datapermission_list_temp = tbl_user_datapermissionDao.getList( paramMap );
		if( user_datapermission_list_temp != null && !user_datapermission_list_temp.isEmpty() ) {
			for( Tbl_user_datapermission permission : user_datapermission_list_temp ) {
				user_datapermission_list.add( permission );
			}
		}
		
		return user_datapermission_list;
	}
	/**
	 * 根据用户获取用户可以访问到的所有灾害体ID列表
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<String> getProjectIdsWithPermission( String login_name ) throws Exception {
		
		List<Tbl_user_datapermission> user_datapermission_list = null;
		
		//先查询用户的所有数据权限信息
		user_datapermission_list = listAllDatapermission( login_name );
		
		return getProjectIdsWithPermission( user_datapermission_list );
	}
	
	/**
	 * 根据用户获取用户可以访问到的所有灾害体ID列表
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<String> getProjectIdsWithPermission( List<Tbl_user_datapermission> user_datapermission_list ) throws Exception {
		Map<String, Object> paramMap = new HashMap<>();
		List<Tbl_project> projects = null;
		List<String> projectIds = new ArrayList<>();
		
		//将所有的权限信息换算为灾害体信息列表
		if( user_datapermission_list != null && !user_datapermission_list.isEmpty() ) {
			for( Tbl_user_datapermission perm : user_datapermission_list ) {
				
				paramMap.clear();
				
				if( "PROVINCE".equals( perm.getPerm_level() )) {
					paramMap.put( "province_code", perm.getPerm_code() );
				}else if( "CITY".equals( perm.getPerm_level() )) {
					paramMap.put( "city_code", perm.getPerm_code() );
				}else if( "COUNTY".equals( perm.getPerm_level() )) {
					paramMap.put( "area_code", perm.getPerm_code() );
				}else if( "PROJECT".equals( perm.getPerm_level() )) {
					paramMap.put( "id", perm.getPerm_code() );
				}else {
					continue;
				}
				
				projects = tbl_projectDao.getList( paramMap );
				if( projects != null && !projects.isEmpty() ) {
					for( Tbl_project project : projects ) {
						if( !projectIds.contains(project.getId() )) {
							projectIds.add( project.getId() );
						}
					}
				}
			}
		}
		return projectIds;
	}
	
	/**
	 * 根据用户获取用户可以访问到的所有区域CODE列表
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<String> getAreaCodesWithPermission( String login_name ) throws Exception {
		List<Tbl_user_datapermission> user_datapermission_list = null;
		
		//先查询用户的所有数据权限信息
		user_datapermission_list = listAllDatapermission( login_name );
		
		return getProjectIdsWithPermission( user_datapermission_list );
	}
	
	/**
	 * 根据用户获取用户可以访问到的所有区域CODE列表
	 * @param map
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<String> getAreaCodesWithPermission( List<Tbl_user_datapermission> user_datapermission_list ) throws Exception {
		Map<String, Object> paramMap = new HashMap<>();
		List<String> areaCodes = new ArrayList<>();
		
		//将所有的权限信息换算为灾害体信息列表
		if( user_datapermission_list != null && !user_datapermission_list.isEmpty() ) {
			for( Tbl_user_datapermission perm : user_datapermission_list ) {
				paramMap.clear();
				if( "PROVINCE".equals( perm.getPerm_level() ) || "CITY".equals( perm.getPerm_level() ) || "COUNTY".equals( perm.getPerm_level() )) {
					areaCodes = addAllAreaCode( perm.getPerm_code(), areaCodes );
				}else {
					continue;
				}
			}
		}
		return areaCodes;
	}
	
	/**
	 * 根据区域组织所有组织编码列表
	 * @param perm_code
	 * @param areaCodes
	 * @return
	 * @throws Exception
	 */
	private List<String> addAllAreaCode( String perm_code, List<String> areaCodes ) throws Exception {
		if( perm_code == null ) {
			throw new Exception("perm_code is null!");
		}
		if( areaCodes == null ) {
			areaCodes = new ArrayList<>();
		}
		if( !areaCodes.contains( perm_code )) {
			areaCodes.add( perm_code );
		}
		//查询所有下级地区
		List<Tbl_area> subAreas = null;
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put( "parent_code", perm_code );
		subAreas = tbl_areaDao.getList( paramMap );
		if( subAreas != null && !subAreas.isEmpty() ) {
			for( Tbl_area area : subAreas ) {
				if( !areaCodes.contains( area.getArea_code() )) {
					areaCodes.add( area.getArea_code() );
				}
			}
		}
		
		return areaCodes;
	}
	
	@Override
	public List<String> getStationIdsWithPermission( String login_name ) throws Exception {
		Map<String, Object> paramMap = new HashMap<>();
		List<Tbl_station_info> station_infos = null;
		List<String> zhtIds = null;
		List<String> stationIds = new ArrayList<>();
		
		zhtIds = getZhtIdsWithPermission( login_name );
		
		if( zhtIds != null && !zhtIds.isEmpty() ) {
			paramMap.put( "zht_ids", zhtIds );
			station_infos = tbl_station_infoDao.getList(paramMap);
			if( station_infos != null && !station_infos.isEmpty() ) {
				for( Tbl_station_info station : station_infos ) {
					if( !stationIds.contains( station.getStation_id() )) {
						stationIds.add( station.getStation_id() );
					}
				}
			}
		}
		
		return stationIds;
	}
	
	/**
	 * 根据用户的登录名以及指定的城市编码，查询该城市类可以访问到的项目ID列表
	 * @param city_code
	 * @param login_name
	 * @return
	 */
	@Override
	public List<String> getVisibleProjectIdsWithCityCodeLoginName( String city_code, String login_name ) {
		Map<String, Object> map = new HashMap<>();
		List<Tbl_zht> zhts = null;
		List<Tbl_project> projects = null;
		List<String> roleCodes = null;
		List<String> sub_area_codes = null;
		List<String> visiableProjectIds = null;
		List<String> user_datapermissionCodes = null;
		
		//可以编辑的项目肯定全部可以看见
		visiableProjectIds = getEditableProjectIdsWithCityCodeLoginName( city_code, login_name );
		
		if( visiableProjectIds == null ) {
			visiableProjectIds = new ArrayList<>();
		}		
		
		//再查询一下用户是否有该城市的某个区的权限
		map.clear();
		map.put( "parent_code", city_code );
		sub_area_codes = tbl_areaDao.getAreaCodes( map );
		if( sub_area_codes != null && !sub_area_codes.isEmpty() ) {
			map.clear();
			roleCodes = listRoleCodesWithLoginName(login_name);
			if( roleCodes == null ) {
				roleCodes = new ArrayList<>();
			}
			roleCodes.add( login_name );
			map.put( "object_codes", roleCodes );
			map.put( "perm_codes", sub_area_codes );
			user_datapermissionCodes = tbl_user_datapermissionDao.getPermCodeList(map);
			if( user_datapermissionCodes != null && !user_datapermissionCodes.isEmpty() ) {
				map.clear();
				map.put( "area_codes", user_datapermissionCodes );
				projects = tbl_projectDao.getList(map);
				if( projects != null && !projects.isEmpty() ) {
					for( Tbl_project project : projects ) {
						if( !visiableProjectIds.contains( project.getId() )) {
							visiableProjectIds.add( project.getId() );
						}
					}
				}
			}
		}
		
		
		//再查询一下灾害体和站点的权限，如果有，也需要让相应的项目可见
		map.clear();
		roleCodes = listRoleCodesWithLoginName( login_name );
		if( roleCodes == null ) {
			roleCodes = new ArrayList<>();
		}
		roleCodes.add( login_name );
		map.put( "object_codes", roleCodes );
		map.put( "perm_level", "ZHT" );
		//查询用户可以控制的灾害体，然后查询该灾害体所在的项目，加入到可见范畴
		user_datapermissionCodes = tbl_user_datapermissionDao.getPermCodeList(map);
		if( user_datapermissionCodes != null && !user_datapermissionCodes.isEmpty() ) {
			map.clear();
			map.put( "ids", user_datapermissionCodes );
			zhts = tbl_zhtDao.getList( map );
			if( zhts != null && !zhts.isEmpty() ) {
				for( Tbl_zht zht : zhts ) {
					if( !visiableProjectIds.contains( zht.getProject_id() )) {
						visiableProjectIds.add( zht.getProject_id() );
					}
				}
			}
		}		
		
		return visiableProjectIds;
	}
	
	/**
	 * 根据用户的登录名以及指定的城市编码，查询该城市类可以编辑到的项目ID列表
	 * @param city_code
	 * @param login_name
	 * @return
	 */
	@Override
	public List<String> getEditableProjectIdsWithCityCodeLoginName( String city_code, String login_name ) {
		Tbl_area city = null;
		Map<String, Object> map = new HashMap<>();
		List<String> roleCodes = null;
		List<Tbl_user_datapermission> user_datapermission_list = null;
		
		user_datapermission_list = listDatapermissionWithLoginNameAndAreaCode( city_code, login_name );		
		//如果列表不为空，说明用户或者用户所拥有的角色有该地区的数据控制权限
		if( user_datapermission_list != null && !user_datapermission_list.isEmpty() ) {
			//返回该城市内所有的项目ID列表
			map.clear();
			map.put( "city_code", city_code );
			return tbl_projectDao.getIds(map);
		}
		
		//如果用户没有城市的访问权限，那么查询用户是否有该省份的访问权限
		//先查询城市所属的省份
		map.clear();
		map.put( "area_code", city_code );
		city = tbl_areaDao.get(map);
		if( city != null ) {
			user_datapermission_list = listDatapermissionWithLoginNameAndAreaCode( city.getParent_code(), login_name );
			if( user_datapermission_list != null && !user_datapermission_list.isEmpty() ) {
				//返回该城市内所有的项目ID列表
				map.clear();
				map.put( "city_code", city_code );
				return tbl_projectDao.getIds(map);
			}
		}
		
		//如果用户没有城市和省份的访问权限，那么看看用户有哪些项目的访问权限，返回所有列表
		map.clear();
		roleCodes = listRoleCodesWithLoginName(login_name);
		if( roleCodes == null ) {
			roleCodes = new ArrayList<>();
		}
		roleCodes.add( login_name );
		map.put( "object_codes", roleCodes );
		map.put( "perm_level", "PROJECT" );
		return tbl_user_datapermissionDao.getPermCodeList( map );
	}
	
	/**
	 * 根据用户的登录名以及地区编码，查询数据权限对象列表
	 * @param city_code
	 * @param login_name
	 * @return
	 */
	private List<Tbl_user_datapermission> listDatapermissionWithLoginNameAndAreaCode( String city_code, String login_name ) {
		if( city_code == null || city_code.equals( "0" )) {
			return null;
		}
		
		List<String> roleCodes = null;
		Map<String, Object> map = new HashMap<>();
		List<Tbl_user_datapermission> user_datapermission_list = null;
		
		map.put( "object_code", login_name );
		map.put( "perm_code", city_code );
		//先查询用户自己是否有该城市的访问权限，如果有就返回该城市内所有的项目ID列表
		user_datapermission_list = tbl_user_datapermissionDao.getList( map );
		
		if( user_datapermission_list == null || user_datapermission_list.isEmpty() ) {
			roleCodes = listRoleCodesWithLoginName( login_name );
			map.clear();
			map.put( "object_codes", roleCodes );
			map.put( "perm_code", city_code );
			//先查询用户是否有该城市的访问权限，如果有就返回该城市内所有的项目ID列表
			user_datapermission_list = tbl_user_datapermissionDao.getList( map );
		}
		
		return user_datapermission_list;
	}
	
	@Override
	public Boolean isCityController( String login_name, List<String> area_codes ) {
		Integer count = 0;
		List<String> roleCodes = null;
		Map<String, Object> map = new HashMap<>();
		if( area_codes == null || area_codes.isEmpty() ) {
			return false;
		}
		
		roleCodes = listRoleCodesWithLoginName( login_name );
		
		if( roleCodes != null && !roleCodes.isEmpty() ) {
			map.clear();
			map.put( "object_codes", roleCodes );
			map.put( "perm_codes", area_codes );
			count = tbl_user_datapermissionDao.getListCount(map);
			if( count != null && count.intValue() > 0 ) {
				return true;
			}
		}
		
		map.clear();
		map.put( "object_code", login_name );
		map.put( "perm_codes", area_codes );
		count = tbl_user_datapermissionDao.getListCount(map);
		if( count == null || count.intValue() == 0 ) {
			return false;
		}else {
			return true;
		}
	}
	private List<String> listRoleCodesWithLoginName( String login_name ) {
		Tbl_user user = null;
		List<String> roleCodes = null;
		List<String> roleIds = null;
		Map<String, Object> map = new HashMap<>();
		
		map.put( "login_name", login_name );
		user = tbl_userDao.get( map );
		if( user != null ) {
			map.clear();
			map.put( "user_id", user.getId() );
			roleIds = tbl_user_roleDao.listRoleIdsWithFilter( map );
		}
		
		if( roleIds != null  && !roleIds.isEmpty() ) {
			map.clear();
			map.put( "ids", roleIds );
			roleCodes = tbl_roleDao.listRoleCodeWithFilter( map );
		}
		return roleCodes;
	}
	
	
	
}
